package com.kaifamiao.wendao.service;

import com.kaifamiao.wendao.entity.Customer;
import com.kaifamiao.wendao.mapper.CustomerMapper;
import com.kaifamiao.wendao.utils.MessageDigestType;
import com.kaifamiao.wendao.utils.MyBatisHelper;
import com.kaifamiao.wendao.utils.StringHelper;
import org.apache.ibatis.session.SqlSession;

import java.time.LocalDateTime;

public class CustomerService {

    private SqlSession session ;
    private CustomerMapper customerMapper ;

    public void prepare(){
        session = MyBatisHelper.open();
        customerMapper = session.getMapper( CustomerMapper.class );
    }

    /**
     * 完成注册操作 <br>
     * 根据参数传入的 Customer 实例中所包含的数据做出进一步处理后，将其保存到数据库中
     * @param c 需要被继续处理的Customer实例
     * @return
     */
    public boolean register(Customer c){
        // 预备 会话 和 mapper
        prepare();

        // 以当前系统时间为注册时间
        c.setSignUpTime( LocalDateTime.now() );
        // 随机生成盐值
        String salt = StringHelper.random( 10 );
        // 为Customer实例设置盐值
        c.setSalt( salt );
        // 获得用户在页面上所输入的密码
        String password = c.getPassword();
        // 对用户输入的密码进行处理(加盐、加密)
        password = process( password , salt );
        // 将加盐加密后的密码重新设置到Customer实例中
        c.setPassword( password );

        // 调用 mapper 中的方法完成保存操作
        int count = customerMapper.save( c );
        // 提交事务
        session.commit();
        // 返回结果
        return count == 1 ;
    }

    /**
     * 根据用户名返回相应的 Customer 对象
     * @param username 被查找的用户名
     * @return 返回与用户名对应的 Customer 对象
     */
    public Customer load( String username ){
        prepare();
        Customer c = customerMapper.find( username );
        return c;
    }

    /**
     * 根据指定的盐值将密码混淆后再加密并返回加密后的字符串
     * @param password 需要被加密的原始密码
     * @param salt 盐值
     * @return 返回加密后的字符串
     */
    public String process( String password , String salt ) {
        int boundary = 5 ;
        // 从盐值中取前五个字符作前缀
        String prefix = salt.substring( 0 , boundary ) ;
        // 从盐值中取后五个字符作后缀
        String suffix = salt.substring( boundary ) ;
        // 使用盐值将原始密码混淆 ( 即将 prefix 、 原始密码 、 suffix 连接在一起 )
        final String source = prefix + password + suffix ;
        // 将混淆后的字符串进行加密
        String encrypted = StringHelper.encrypt( source , MessageDigestType.SHA1 , StringHelper.UTF8 );
        // 返回加密后的字符串
        return encrypted ;
    }
}
